package com.m3958.firstgwt.server.servlet;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Splitter;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.persist.Transactional;
import com.m3958.firstgwt.server.dao.ArticleDao;
import com.m3958.firstgwt.server.dao.SectionDao;
import com.m3958.firstgwt.server.dao.UserDao;
import com.m3958.firstgwt.server.model.Article;
import com.m3958.firstgwt.server.model.KeyValue;
import com.m3958.firstgwt.server.model.Section;
import com.m3958.firstgwt.server.model.User;
import com.m3958.firstgwt.server.model.WebSite;
import com.m3958.firstgwt.server.model.XinJian;
import com.m3958.firstgwt.server.model.XinJianCat;
import com.m3958.firstgwt.server.session.SessionUser;
import com.m3958.firstgwt.server.utils.Osdetecter;


@Singleton
public class MigrationServlet extends HttpServlet{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private ObjectMapper mapper = new ObjectMapper();
	
	@Inject
	private Injector injector;
	
	
	@Inject
	protected com.google.inject.Provider<EntityManager> emp;

	
	private static final Splitter SECTION_ID_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
	
	public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		
		UserDao udao = injector.getInstance(UserDao.class);
		
		User user = udao.findByLoginName("superman");
		WebSite ws = emp.get().find(WebSite.class, Integer.valueOf(req.getParameter("siteid")));
		
			String action = req.getParameter("action");
			String rb = getRequestContent(req);
			if("section".equals(action)){
				processSection(req,res,ws,user,rb);
			}else if("article".equals(action)){
				processArticle(req,res,ws,user,rb);
			}else if("liuyan".equals(action)){
				processXinJian(req,res,ws,user,rb);
			}
		  
		Writer out = res.getWriter();
		out.write(rb);
	}
	
	private String getRequestContent(HttpServletRequest req) throws IOException{
		  StringBuffer jb = new StringBuffer();
		  String line = null;
		    BufferedReader reader = req.getReader();
		    while ((line = reader.readLine()) != null){
		    	jb.append(line);
		    }
		  return jb.toString();
	}
	
	@Transactional
	public void processXinJian(HttpServletRequest req, HttpServletResponse res,WebSite site,User user,String rb) throws JsonParseException, JsonMappingException, IOException {
		Map<String, Object> xjMap = new HashMap<String,Object>();
		xjMap = mapper.readValue(rb, xjMap.getClass());
		
		Query q = emp.get().createNamedQuery(KeyValue.NamedQueries.FIND_VALUE_BY_NAME_AND_KEY);
		
		String xjcatStr = req.getParameter("xjcatid");
		Integer xjcatid = Integer.valueOf(xjcatStr);
		
		String oldXjId = (String) xjMap.get("id");
		Integer newXjId = getMyValue(q,xjcatStr, oldXjId);
		
		
		XinJianCat xjc = emp.get().find(XinJianCat.class, xjcatid);
		
		if(newXjId == null){//尚未保存的条目
			XinJian xj = new XinJian();
			xj.setTitle((String) xjMap.get("title"));
			xj.setXingming((String) xjMap.get("xingming"));
			xj.setContent((String) xjMap.get("body"));
			
			xj.setShouji((String) xjMap.get("shouji"));
			xj.setEmail((String) xjMap.get("email"));
			
			xj.setCreatedAt(xjMap.get("createdAt") == null ? new Date() : new Date((Long) xjMap.get("createdAt")));
			xj.setRepliedAt(xjMap.get("updatedAt") == null ? new Date() : new Date((Long) xjMap.get("updatedAt")));
			xj.setPublishedAt(xjMap.get("publishedAt") == null ? new Date() : new Date((Long) xjMap.get("publishedAt")));
			
			xj.setDanwei((String) xjMap.get("danwei"));
			
			xj.setDianhua((String) xjMap.get("dianhua"));
			
			xj.setDizhi((String) xjMap.get("dizhi"));
			
			xj.setLeixing((String) xjMap.get("mudi"));
			
			xj.setReply((String) xjMap.get("replyBody"));
			
			String state = (String) xjMap.get("state");
			if("REPLIED".equals(state)){
				xj.setState(state);
			}else{
				xj.setState("UNTOUCHED");
			}
			xj.setGongkai(true);
			xj.setAudit(true);
			xj.setSiteId(site.getId());
			
			emp.get().persist(xj);
			
			List<XinJian> xjs = xjc.getXinjians();
			xjs.add(xj);
			
			xjc.setXinjians(xjs);
			
			emp.get().merge(xjc);
			
			KeyValue kv = new KeyValue();
			kv.setName(xjcatStr);
			kv.setMykey(oldXjId);
			kv.setMyvalue(String.valueOf(xj.getId()));
			emp.get().persist(kv);
		}else{
		}
	}
	
	/*可以多次发送，如果已经保存，就不保存了。*/
	@Transactional
	public void processArticle(HttpServletRequest req, HttpServletResponse res,WebSite site,User user,String rb) throws JsonParseException, JsonMappingException, IOException {
		Map<String, Object> articleMap = new HashMap<String,Object>();
		articleMap = mapper.readValue(rb, articleMap.getClass());
		Query q = emp.get().createNamedQuery(KeyValue.NamedQueries.FIND_VALUE_BY_NAME_AND_KEY);
		
		String oldArticleId = (String) articleMap.get("id");
		Integer newArticleId = getMyValue(q,"site-migration-section", oldArticleId);
		
		if(newArticleId == null){//尚未保存的条目
			Article ar = new Article();
			ar.setTitle((String) articleMap.get("title"));
			ar.setExcerpt((String) articleMap.get("excerpt"));
			ar.setContent((String) articleMap.get("body"));
			ar.setCreatedAt(articleMap.get("createdAt") == null ? new Date() : new Date((Long) articleMap.get("createdAt")));
			ar.setUpdatedAt(articleMap.get("updatedAt") == null ? new Date() : new Date((Long) articleMap.get("updatedAt")));
			ar.setPublishedAt(articleMap.get("publishedAt") == null ? new Date() : new Date((Long) articleMap.get("publishedAt")));
			ar.setSiteId(site.getId());
			ar.setCreator(user);
			emp.get().persist(ar);
			
			KeyValue kv = new KeyValue();
			kv.setName("site-migration-section");
			kv.setMykey(oldArticleId);
			kv.setMyvalue(String.valueOf(ar.getId()));
			emp.get().persist(kv);
		}else{
//			Article ar = emp.get().find(Article.class,newArticleId);
//			Iterable<String> sectionids = SECTION_ID_SPLITTER.split((String) articleMap.get("sectionids"));
//			for(Iterator<String> it = sectionids.iterator();it.hasNext();){
//				Integer sectionId = getMyValue(q, it.next());
////				Section s = emp.get().find(Section.class, sectionId);
////				if(s != null){
////					s.getArticles().add(ar);
////					emp.get().merge(s);
////					ar.getSections().add(s);
//				if(sectionId != null){
//					ar.setDefaultSectionId(sectionId);
//				}
////				}
//			}
//			if(ar!=null){
//				emp.get().merge(ar);
//			}
		}
	}

	@Transactional
	public void processSection(HttpServletRequest req, HttpServletResponse res,WebSite site,User user,String rb) throws JsonParseException, JsonMappingException, IOException {
		Map<String, Object> sectionMap = new HashMap<String,Object>();
		sectionMap = mapper.readValue(rb, sectionMap.getClass());
		Query q = emp.get().createNamedQuery(KeyValue.NamedQueries.FIND_VALUE_BY_NAME_AND_KEY);
		
		String oldSectionId = (String) sectionMap.get("id");
		Integer newSectionId = getMyValue(q,"site-migration-section", oldSectionId);
		
		if(newSectionId == null){//尚未保存的条目
			Section s = new Section();
			s.setSiteId(site.getId());
			s.setName((String) sectionMap.get("name"));
			s.setCreator(user);
			
			List<String> articleids = (List<String>) sectionMap.get("articleids");
			List<Article> articles = new ArrayList<Article>();
			for(String articleIdStr : articleids){
				Integer articleId = getMyValue(q,"site-migration-section", articleIdStr);
				Article ar = null;
				if(articleId != null){
					try {
						ar = emp.get().find(Article.class, articleId);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				if(ar != null){
					articles.add(ar);
				}
			}
			s.setArticles(articles);
			emp.get().persist(s);
			
			for(Article ar : articles){
				ar.setDefaultSectionId(s.getId());
				emp.get().merge(ar);
			}
			KeyValue kv = new KeyValue();
			kv.setName("site-migration-section");
			kv.setMykey(oldSectionId);
			kv.setMyvalue(String.valueOf(s.getId()));
			emp.get().persist(kv);
		}else{//已保存的条目，设置父子关系。
			Section s = null;
			try {
				s = emp.get().find(Section.class, newSectionId);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if(s == null)return;
			String oldParentId = (String) sectionMap.get("parentId");
			Integer newParentId = getMyValue(q,"site-migration-section", oldParentId);
			if(newParentId != null){
				Section newParent = null;
				try {
					newParent = emp.get().find(Section.class, newParentId);
				} catch (Exception e) {
					e.printStackTrace();
				}
				s.setParent(newParent);
				emp.get().merge(s);
				if(newParent != null){
					newParent.getChildren().add(s);
					emp.get().merge(newParent);
				}
			}
		}
	}

	private Integer getMyValue(Query q,String name,String mykey){
		q.setParameter("name", name);
		q.setParameter("mykey", mykey);
		try {
			String value = (String) q.getSingleResult();
			return Integer.valueOf(value);
		} catch (Exception e) {
			return null;
		}
	}

}
